package com.spider.silence.abstarct.downloader;

import com.google.common.collect.Sets;
import com.spider.silence.constant.Constant;
import com.spider.silence.itf.downloader.DownLoader;
import com.spider.silence.proxy.ProxyPool;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.jsoup.nodes.Document;
import org.openqa.selenium.Cookie;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.downloader.HttpClientDownloader;
import us.codecraft.webmagic.proxy.Proxy;
import us.codecraft.webmagic.proxy.SimpleProxyProvider;
import us.codecraft.webmagic.utils.HttpConstant;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 夏茂轩 on 2016/12/16.
 */
public  abstract class AbstractCommonDownLoader implements DownLoader {
    public HashMap<String,String> headers=new HashMap<String, String>();
    public Request request =new Request();
    public HttpClientDownloader downloader =new HttpClientDownloader();
    public Task task=null;
    public HashSet<Cookie> cookies=new HashSet<Cookie>();

    @Override
    public Document get(String url) throws Exception {
        return get(url,null);
    }

    @Override
    public String getString(String url) throws  Exception{
        return getString(url,null);
    }

    @Override
    public String getString(String url,final String proxy)throws Exception {
        downloader.setThread(10);
        request.setUrl(url);
        task=new Task() {
            @Override
            public String getUUID() {
                return UUID.randomUUID().toString();
            }
            @Override
            public Site getSite() {
                Site site = new Site();
                site.setUserAgent(Constant.HTTP_USER_AGENT);
                site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setTimeOut(Constant.HTTP_TIME_OUT);
                site.setAcceptStatCode(Sets.newHashSet(403,200));
                if(proxy!=null){
                    try {
                        String[] proxyArray=proxy.split(":");
                        //HttpHost httpHost =new HttpHost(proxyArray[0],Integer.parseInt(proxyArray[1]));
                        //site.setHttpProxy(httpHost);
                        downloader.setProxyProvider(SimpleProxyProvider.from(new Proxy(proxyArray[0],Integer.parseInt(proxyArray[1]))));

                    } catch (Exception e) {
                        System.out.printf("代理格式错误");
                    }
                }
                if(headers!=null){
                    for(Map.Entry<String, String> entry:headers.entrySet()){
                        site.addHeader(entry.getKey(),entry.getValue());
                    }
                }
                if(cookies!=null){
                    for (Cookie cookie : cookies) {
                        site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                    }
                }
                return site;
            }
        };
        return downloader.download(request,task).getRawText();
    }

    @Override
    public Page getHtml(String url) throws Exception{
        return  getHtml(url,null);
    }

    @Override
    public Page getHtml(String url,final String proxy) throws Exception{
        downloader.setThread(10);
        request.setUrl(url);
        task=new Task() {
            @Override
            public String getUUID() {
                return UUID.randomUUID().toString();
            }
            @Override
            public Site getSite() {
                Site site = new Site();
                site.setUserAgent(Constant.HTTP_USER_AGENT);
                site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setTimeOut(Constant.HTTP_TIME_OUT);
                site.setAcceptStatCode(Sets.newHashSet(403,200));
                if(proxy!=null){
                    try {
                        String[] proxyArray=proxy.split(":");
                        HttpHost httpHost =new HttpHost(proxyArray[0],Integer.parseInt(proxyArray[1]));
                        downloader.setProxyProvider(SimpleProxyProvider.from(new Proxy(proxyArray[0],Integer.parseInt(proxyArray[1]))));
                        //site.setHttpProxy(httpHost);
                    } catch (Exception e) {
                        System.out.printf("代理格式错误");
                    }
                }
                if(headers!=null){
                    for(Map.Entry<String, String> entry:headers.entrySet()){
                        site.addHeader(entry.getKey(),entry.getValue());
                    }
                }
                if(cookies!=null){
                    for (Cookie cookie : cookies) {
                        site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                    }
                }
                return site;
            }
        };
        return downloader.download(request,task);
    }

    @Override
    public Page getHtml(String url, final boolean isProxy) throws Exception{
        downloader.setThread(10);
        request.setUrl(url);
        task=new Task() {
            @Override
            public String getUUID() {
                return UUID.randomUUID().toString();
            }
            @Override
            public Site getSite() {
                Site site = new Site();
                site.setUserAgent(Constant.HTTP_USER_AGENT);
                site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setTimeOut(Constant.HTTP_TIME_OUT);
                if(isProxy){
                    try {
                        downloader.setProxyProvider(SimpleProxyProvider.from(ProxyPool.proxyArray()));
                        downloader.setThread(10);
                    } catch (Exception e) {
                        System.out.printf("代理格式错误");
                    }
                }
                if(headers!=null){
                    for(Map.Entry<String, String> entry:headers.entrySet()){
                        site.addHeader(entry.getKey(),entry.getValue());
                    }
                }
                if(cookies!=null){
                    for (Cookie cookie : cookies) {
                        site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                    }
                }
                return site;
            }
        };
        return downloader.download(request,task);
    }

    @Override
    public String getString(String url,final boolean isProxy){
        downloader.setThread(10);
        request.setUrl(url);
        task=new Task() {
            @Override
            public String getUUID() {
                return UUID.randomUUID().toString();
            }
            @Override
            public Site getSite() {
                Site site = new Site();
                site.setUserAgent(Constant.HTTP_USER_AGENT);
                site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setTimeOut(Constant.HTTP_TIME_OUT);
                if(isProxy){
                    try {
                        downloader.setProxyProvider(SimpleProxyProvider.from(ProxyPool.proxyArray()));
                    } catch (Exception e) {
                        System.out.printf("代理格式错误");
                    }
                }
                if(headers!=null){
                    for(Map.Entry<String, String> entry:headers.entrySet()){
                        site.addHeader(entry.getKey(),entry.getValue());
                    }
                }
                if(cookies!=null){
                    for (Cookie cookie : cookies) {
                        site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                    }
                }
                return site;
            }
        };
        return downloader.download(request,task).getRawText();
    };

    @Override
    public Document get(String url, final String proxy) throws Exception {
        downloader.setThread(10);
        request.setUrl(url);
        task=new Task() {
                @Override
                public String getUUID() {
                    return UUID.randomUUID().toString();
                }
                @Override
                public Site getSite() {
                    Site site = new Site();
                    site.setUserAgent(Constant.HTTP_USER_AGENT);
                    site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                    site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                    site.setTimeOut(Constant.HTTP_TIME_OUT);
                    if(proxy!=null){
                        try {
                            String[] proxyArray=proxy.split(":");
                            HttpHost httpHost =new HttpHost(proxyArray[0],Integer.parseInt(proxyArray[1]));
                            downloader.setProxyProvider(SimpleProxyProvider.from(new Proxy(proxyArray[0],Integer.parseInt(proxyArray[1]))));
                            //site.setHttpProxy(httpHost);
                        } catch (Exception e) {
                            System.out.printf("代理格式错误");
                        }
                    }
                    if(headers!=null){
                        for(Map.Entry<String, String> entry:headers.entrySet()){
                            site.addHeader(entry.getKey(),entry.getValue());
                        }
                    }
                    if(cookies!=null){
                        for (Cookie cookie : cookies) {
                            site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                        }
                    }
                    return site;
                }
            };

        return downloader.download(request,task).getHtml().getDocument();
    }

    public Document get(String url, final boolean isProxy) throws Exception {
        downloader.setThread(10);
        request.setUrl(url);
        task=new Task() {
            @Override
            public String getUUID() {
                return UUID.randomUUID().toString();
            }
            @Override
            public Site getSite() {
                Site site = new Site();
                site.setUserAgent(Constant.HTTP_USER_AGENT);
                site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setTimeOut(Constant.HTTP_TIME_OUT);
                site.setRetrySleepTime(20);
                //site.setSleepTime(20);
                if(isProxy){
                    try {
                        //site.setHttpProxyPool(ProxyPool.proxyList(),false);
                        downloader.setProxyProvider(SimpleProxyProvider.from(ProxyPool.proxyArray()));
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.printf("代理格式错误");
                    }
                }
                if(headers!=null){
                    for(Map.Entry<String, String> entry:headers.entrySet()){
                        site.addHeader(entry.getKey(),entry.getValue());
                    }
                }
                if(cookies!=null){
                    for (Cookie cookie : cookies) {
                        site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                    }
                }
                return site;
            }
        };
        return downloader.download(request,task).getHtml().getDocument();
    }

    @Override
    public Document post(String url) throws Exception {
        return post(url,null,null);
    }

    @Override
    public Document post(String url, String proxy) throws Exception {
        return post(url,null,proxy);
    }
    @Override
    public Document post(String url, boolean isProxy) throws Exception {
        return post(url,null,isProxy);
    }

    @Override
    public Document post(String url, Map<String, String> params) throws Exception {
        return post(url,params,null);
    }

    @Override
    public Document post(String url, final Map<String, String> params, final String proxy) throws Exception {
        downloader.setThread(10);
        task=new Task() {
            @Override
            public String getUUID() {
                return UUID.randomUUID().toString();
            }
            @Override
            public Site getSite() {
                Site site = new Site();
                site.setUserAgent(Constant.HTTP_USER_AGENT);
                site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setTimeOut(Constant.HTTP_TIME_OUT);
                site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                if(proxy!=null){
                    try {
                        String[] proxyArray=proxy.split(":");
                        HttpHost httpHost =new HttpHost(proxyArray[0],Integer.parseInt(proxyArray[1]));
                        downloader.setProxyProvider(SimpleProxyProvider.from(new Proxy(proxyArray[0],Integer.parseInt(proxyArray[1]))));
                        //site.setHttpProxy(httpHost);
                    } catch (Exception e) {
                        System.out.printf("代理格式错误");
                    }
                }
                if(headers!=null){
                    for(Map.Entry<String, String> entry:headers.entrySet()){
                        site.addHeader(entry.getKey(),entry.getValue());
                    }
                }
                if(cookies!=null){
                    for (Cookie cookie : cookies) {
                        site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                    }
                }
                return site;
            }
        };
        Request request2 = new Request(url);
        NameValuePair[] values = new NameValuePair[params.size()];
        if(params!=null){
            int i=0;
            for(Map.Entry<String, String> entry:params.entrySet()){
                values[i] = new BasicNameValuePair(entry.getKey(),entry.getValue());
                i++;
            }
        };
        Map nameValuePair = new HashMap();
        nameValuePair.put("nameValuePair", values);
        request2.setExtras(nameValuePair);
        request2.setMethod(HttpConstant.Method.POST);
        return downloader.download(request2,task).getHtml().getDocument();

    }
    @Override
    public Document post(String url, Map<String,String> params, final boolean isProxy)  throws Exception{
        downloader.setThread(10);
        task=new Task() {
            @Override
            public String getUUID() {
                return UUID.randomUUID().toString();
            }
            @Override
            public Site getSite() {
                Site site = new Site();
                site.setUserAgent(Constant.HTTP_USER_AGENT);
                site.setRetryTimes(Constant.HTTP_RETRY_TIMES);
                site.setTimeOut(Constant.HTTP_TIME_OUT);
                site.setCycleRetryTimes(Constant.HTTP_RETRY_TIMES);
                if(isProxy){
                    try {
                        //site.setHttpProxyPool(ProxyPool.proxyList(),true);
                        downloader.setProxyProvider(SimpleProxyProvider.from(ProxyPool.proxyArray()));
                    } catch (Exception e) {
                        System.out.printf("代理格式错误");
                    }
                }
                if(headers!=null){
                    for(Map.Entry<String, String> entry:headers.entrySet()){
                        site.addHeader(entry.getKey(),entry.getValue());
                    }
                }
                if(cookies!=null){
                    for (Cookie cookie : cookies) {
                        site.addCookie(cookie.getDomain(), cookie.getName(), cookie.getValue());
                    }
                }
                return site;
            }
        };
        Request request2 = new Request(url);
        NameValuePair[] values = new NameValuePair[params.size()];
        if(params!=null){
            int i=0;
            for(Map.Entry<String, String> entry:params.entrySet()){
                values[i] = new BasicNameValuePair(entry.getKey(),entry.getValue());
                i++;
            }
        };
        Map nameValuePair = new HashMap();
        nameValuePair.put("nameValuePair", values);
        request2.setExtras(nameValuePair);
        request2.setMethod(HttpConstant.Method.POST);
        return downloader.download(request2,task).getHtml().getDocument();
    }
    /**
     * 构造方法设置 请求头
     * @param headers
     */
    public AbstractCommonDownLoader(HashMap<String, String> headers) {
        this.headers = headers;
    }

    public AbstractCommonDownLoader() {
    }

    public boolean init(){
        return  true;
    }

    public Map<String, Object> getUrlParams(String param) {
        Map<String, Object> map = new HashMap<String, Object>(0);
        if (StringUtils.isBlank(param)) {
            return map;
        }
        String[] params = param.split("\\?")[1].split("&");
        for (int i = 0; i < params.length; i++) {
            String[] p = params[i].split("=");
            if (p.length == 2) {
                map.put(p[0], p[1]);
            }
        }
        return map;
    }

    public  String  getTime(String content){
        try {
            List matches = null;
            Pattern p = Pattern.compile("(\\d{1,4}[-|\\/|年|\\.]\\d{1,2}[-|\\/|月|\\.]\\d{1,2}([日|号])?(\\s)*(\\d{1,2}([点|时])?((:)?\\d{1,2}(分)?((:)?\\d{1,2}(秒)?)?)?)?(\\s)*(PM|AM)?)", Pattern.CASE_INSENSITIVE|Pattern.MULTILINE);
            Matcher matcher = p.matcher(content);
            if (matcher.find() && matcher.groupCount() >= 1) {
                matches = new ArrayList();
                for (int i = 1; i <= matcher.groupCount(); i++) {
                    String temp = matcher.group(i);
                    matches.add(temp);
                }
            } else {
                matches = Collections.EMPTY_LIST;
            }
            if (matches.size() > 0) {
                return ((String) matches.get(0)).trim();
            } else {
            }
        } catch (Exception e) {
            return "";
        }
        return content;
    }
}
